package cn.qrx.gateway.bind;

import cn.qrx.gateway.session.Configuration;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.config.utils.ReferenceConfigCache;
import org.apache.dubbo.rpc.service.GenericService;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 屈燃希
 * @date 2025/10/1 21:16
 * @content
 */
public class GenericReferenceRegistry {

    // 配置信息，用于存储和管理应用程序的配置
    private  final Configuration configuration;


    // 已知的泛型引用代理工厂映射表，以方法名为键
    private final Map<String,GenericReferenceProxyFactory> knownGenericReferences=new HashMap<>();
    /**
     * 构造函数
     * @param configuration 配置信息对象
     */
    public GenericReferenceRegistry(Configuration configuration) {
        this.configuration = configuration;
    }

    /**
     * 获取泛型引用
     * @param method 方法名
     * @return 泛型引用接口
     * @throws RuntimeException 如果找不到对应的泛型引用
     */
    public IGenericReference getGenericReference(String method) {
        // 从已知映射表中获取泛型引用代理工厂
        GenericReferenceProxyFactory genericReferenceProxyFactory = knownGenericReferences.get(method);
        if (genericReferenceProxyFactory == null) {
            throw new RuntimeException("GenericReference not found");
        }
        // 创建并返回新的泛型引用实例
        return genericReferenceProxyFactory.newInstance(method);
    }

    /**
     * 添加泛型引用
     * @param application 应用名称
     * @param method 方法名
     * @param interfaceName 接口名称
     */
    public void addGenericReference(String application,String method,String interfaceName) {

        // 获取应用配置
        ApplicationConfig applicationConfig = configuration.getApplicationConfig(application);
        // 获取引用配置
        ReferenceConfig<GenericService> referenceConfig = configuration.getReferenceConfig(interfaceName);
        // 获取注册中心配置
        RegistryConfig registryConfig = configuration.getRegistryConfig(application);

        // 创建并启动Dubbo引导实例
        DubboBootstrap bootstrap = DubboBootstrap.getInstance();
        bootstrap.application(applicationConfig).registry(registryConfig).reference(referenceConfig).start();

        // 获取引用配置缓存并获取泛型服务
        ReferenceConfigCache cache =ReferenceConfigCache.getCache();
        GenericService genericService = cache.get(referenceConfig);
        // 将泛型引用代理工厂存入已知映射表
        knownGenericReferences.put(method,new GenericReferenceProxyFactory(genericService));
    }
}
